#include <at89x52.h>
#include "main.h"

#define DIO P1_4
#define CLK P1_5
#define STB P1_6


static void tm1668_delay()
{
    int8_t i;
    for (i = 0; i < 58; ++i)
        ;
}

#if 0
static void tm1668_rw(int8_t is_read, uint8_t *val)
{
    int8_t i;
    tm1668_delay();
    for (i = 0; i < 8; ++i) {
        CLK = 0;
        if (!is_read) DIO = (*val >> i) & 0x01; // write
        tm1668_delay();
        if (is_read) *val = (*val << 1) + DIO; // read
        CLK = 1;
        tm1668_delay();
    }
    DIO = 1;
}
#endif

enum stb_enum{CMD_only = 1, CMD_data = 0, DATA_mid = 0, DATA_end = 1};

static void tm1668_w(enum stb_enum type, uint8_t val)
{
    int8_t i;
    STB = 0; // all type
    tm1668_delay();
    for (i = 0; i < 8; ++i) {
        CLK = 0;
        DIO = (val >> i) & 0x01; // write
        tm1668_delay();
        CLK = 1;
        tm1668_delay();
    }
    DIO = 1;
    STB = type;
    tm1668_delay();
}

const static num_tab[] = {0xaf, 0x22, 0xb5, 0xb6, 0x3a, 0x9e, 0x9f, 0x26, 0xbf, 0xbe};

int8_t tm1668_num = 0;

#define TM_LED_R_D (1 << 4)
uint8_t tm1668_led = TM_LED_R_D;

void tm1668_update(void)
{
    //tm1668_w(CMD_only, 0x8b); // show 10/16
    tm1668_w(CMD_only, 0x8a); // show 4/16
    tm1668_w(CMD_only, 0x40); // write display reg command

    // if (tm1668_num < 0) tm1668_num = 0;
    // if (tm1668_num > 99) tm1668_num = 99;

    tm1668_w(CMD_data, 0xc0); // addr set 00H
    tm1668_w(DATA_end, tm1668_led); // data led

    tm1668_w(CMD_data, 0xc2); // addr set 02H
    tm1668_w(DATA_end, num_tab[tm1668_num%10]);
    tm1668_w(CMD_data, 0xc4); // addr set 04H
    tm1668_w(DATA_end, num_tab[tm1668_num/10]);
}

void tm1668_init(void)
{
    // tm1668_w(CMD_only, 0x8f); // show
    // tm1668_w(CMD_only, 0x40); // write display reg command

    tm1668_update();
}
